﻿using DynamicAuthorization.Sdk.Attributes;
using Newtonsoft.Json;
using OA.Infrastructure.DomainModels.TemporaryAuthorization;
using OA.Infrastructure.Extensions;

namespace OA.Infrastructure.Controllers;

[ApiController]
[PermisstionDefinition("用户管理", Route = "/organization/user")]
public class UserController : ControllerBase
{
    private readonly IUserService _service;

    public UserController(IUserService service)
    {
        _service = service;
    }

    // GET api/user
    [HttpGet("api/user")]
    public Task<ListResult<User.QueryModel>> GetListAsync()
    {
        return _service.GetListAsync(HttpContext.RequestAborted);
    }

    // GET api/user/condition-selector
    [HttpGet("api/user/condition-selector")]
    public Task<PageResult<User.QueryModel>> GetPageAsync([FromQuery] User.ConditionSelectorCondition condition)
    {
        return _service.GetPageAsync(condition, HttpContext.RequestAborted);
    }

    // PUT api/user/5
    [HttpPut("api/user/{id}")]
    [DynamicAuthorize]
    [PermisstionDefinition("更新用户")]
    public Task<OperationalResult> UpdateAsync(int id, User.UpdateModel user)
    {
        return _service.UpdateAsync(id, user, HttpContext.RequestAborted);
    }


#if DEBUG
    // GET api/demo/condition-selector
    [HttpGet("api/demo/condition-selector")]
    public async Task<PageResult<User.QueryModel>> GetDemoPageAsync([FromQuery] User.ConditionSelectorCondition condition)
    {
        var result = await _service.GetPageAsync(condition, HttpContext.RequestAborted);

        var data = result.Data.ToList();

        foreach (var item in data)
        {
            item.Name = ToSensitization(item.Name);
        }

        result.Data = data;


        return result;
    }

    // GET api/demo/condition-selector
    [HttpGet("api/demo/temp-auth-one")]
    public async Task<OperationalResult<User.QueryModel>> GetTempAuthOneAsync([FromQuery] string key, string code)
    {
        var result = new OperationalResult<User.QueryModel>();

        var context = HttpContext.RequestServices.GetRequiredService<DbContext>();
        var temporaryService = HttpContext.RequestServices.GetRequiredService<ITemporaryAuthorizationService<TemporaryAuthorizationCodeModel>>();

        if (temporaryService.TryConsume(key, code, out var model))
        {
            var user = await context.Set<User>()
                .Include(m => m.Roles)
                .Include(x => x.DirectLeader).ThenInclude(x => x.DirectLeader)
                .Include(x => x.DirectLeader).ThenInclude(x => x.Department)
                .Include(m => m.Department).ThenInclude(x => x.Leader)
                .Include(m => m.Department).ThenInclude(x => x.Parent)
                .Include(m => m.Department).ThenInclude(x => x.Roles)
                .Where(x => x.Account == model!.Target)
                .AsNoTracking()
                .FirstOrDefaultAsync(HttpContext.RequestAborted);

            if (user is not null)
            {
                result.Data = DefinitionServiceExtensions.GetUserQueryModel(user);

                return result;
            }
        }

        return OperationalResult<User.QueryModel>.Fail("授权码错误");
    }

    // POST api/demo/acquire
    [HttpPost("api/demo/acquire")]
    public async Task<string> TryAcquireAsync()
    {
        using var reader = new StreamReader(Request.Body);

        var model = JsonConvert.DeserializeObject<TemporaryAuthorizationCodeModel>(await reader.ReadToEndAsync());

        var temporaryService = HttpContext.RequestServices.GetRequiredService<ITemporaryAuthorizationService<TemporaryAuthorizationCodeModel>>();

        return await temporaryService.TryAcquireAsync(model, HttpContext.RequestAborted);
    }

    // POST api/demo/grant
    [HttpPost("api/demo/grant")]
    public async Task GrantAsync()
    {
        var temporaryService = HttpContext.RequestServices.GetRequiredService<ITemporaryAuthorizationService<TemporaryAuthorizationCodeModel>>();

        using var reader = new StreamReader(Request.Body);

        await temporaryService.GrantAsync(await reader.ReadToEndAsync(), HttpContext.RequestAborted);
    }

    // POST api/demo/reject
    [HttpPost("api/demo/reject")]
    public async Task RejectAsync()
    {
        var temporaryService = HttpContext.RequestServices.GetRequiredService<ITemporaryAuthorizationService<TemporaryAuthorizationCodeModel>>();

        using var reader = new StreamReader(Request.Body);

        await temporaryService.RejectAsync(await reader.ReadToEndAsync(), HttpContext.RequestAborted);
    }

    private static string ToSensitization(string origin)
    {
        return origin.Length == 2
            ? $"{origin[0]}*"
            : $"{origin[0]}{string.Create(origin.Length - 2, "*", (x, _) => x.Fill('*'))}{origin[^1]}";
    }
#endif
}